home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_13_11 / phillip2 / edges.c < prev    next >
C/C++ Source or Header  |  1993-08-11  |  39KB  |  1,563 lines

  1.  
  2.    /*************************** 
  3.    * 
  4.    *   edges.c 
  5.    *   COMPOSITE FILE COMPRISING: 
  6.    *   edge.c 
  7.    *   edge2.c 
  8.    *   edge3.c 
  9.    * 
  10.    ***************************\ 
  11.  
  12.  
  13.  
  14.  
  15.        /***********************************************
  16.        *
  17.        *       file d:\cips\edge.c
  18.        *
  19.        *       Functions: This file contains
  20.        *          detect_edges
  21.        *          setup_masks
  22.        *          get_edge_options
  23.        *          perform_convolution
  24.        *          quick_edge
  25.        *          fix_edges
  26.        *
  27.        *       Purpose:
  28.        *          These functions implement several
  29.        *          types of basic edge detection.
  30.        *
  31.        *       External Calls:
  32.        *          wtiff.c - round_off_image_size
  33.        *                    create_file_if_needed
  34.        *                    write_array_into_tiff_image
  35.        *          tiff.c - read_tiff_header
  36.        *          rtiff.c - read_tiff_image
  37.        *          numcvrt.c - get_integer
  38.        *
  39.        *
  40.        *       Modifications:
  41.        *          27 January 1991 - created
  42.        *          27 December 1992 - Fixed an error in
  43.        *              how I did the 8 direction edge
  44.        *              detectors.  I was only detecting
  45.        *              edges in the last (the 7)
  46.        *              direction.  I fixed this by
  47.        *              setting the out_image to the sum
  48.        *              only if the sum was greater than
  49.        *              the out_image.  This is in the
  50.        *              function perform_convolution.
  51.        *
  52.        *************************************************/
  53.  
  54. #include "cips.h"
  55.  
  56.  
  57.  
  58.  
  59.  
  60. short quick_mask[3][3] =  {
  61.        {-1,  0, -1},
  62.        { 0,  4,  0},
  63.        {-1,  0, -1} };
  64.  
  65.  
  66.    /***************************
  67.    *
  68.    *   Directions for the masks
  69.    *  3 2 1
  70.    *  4 x 0
  71.    *  5 6 7
  72.    *
  73.    ****************************/
  74.  
  75.    /* masks for kirsch operator */
  76. short kirsch_mask_0[3][3] =  {
  77.        { 5,  5,  5},
  78.        {-3,  0, -3},
  79.        {-3, -3, -3} };
  80.  
  81. short kirsch_mask_1[3][3] =  {
  82.        {-3,  5,  5},
  83.        {-3,  0,  5},
  84.        {-3, -3, -3} };
  85.  
  86. short kirsch_mask_2[3][3] =  {
  87.        {-3, -3,  5},
  88.        {-3,  0,  5},
  89.        {-3, -3,  5} };
  90.  
  91. short kirsch_mask_3[3][3] =  {
  92.        {-3, -3, -3},
  93.        {-3,  0,  5},
  94.        {-3,  5,  5} };
  95.  
  96. short kirsch_mask_4[3][3] =  {
  97.        {-3, -3, -3},
  98.        {-3,  0, -3},
  99.        { 5,  5,  5} };
  100.  
  101. short kirsch_mask_5[3][3] =  {
  102.        {-3, -3, -3},
  103.        { 5,  0, -3},
  104.        { 5,  5, -3} };
  105.  
  106. short kirsch_mask_6[3][3] =  {
  107.        { 5, -3, -3},
  108.        { 5,  0, -3},
  109.        { 5, -3, -3} };
  110.  
  111. short kirsch_mask_7[3][3] =  {
  112.        { 5,  5, -3},
  113.        { 5,  0, -3},
  114.        {-3, -3, -3} };
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121.    /* masks for prewitt operator */
  122.  
  123. short prewitt_mask_0[3][3] =  {
  124.        { 1,  1,  1},
  125.        { 1, -2,  1},
  126.        {-1, -1, -1} };
  127.  
  128. short prewitt_mask_1[3][3] =  {
  129.        { 1,  1,  1},
  130.        { 1, -2, -1},
  131.        { 1, -1, -1} };
  132.  
  133. short prewitt_mask_2[3][3] =  {
  134.        { 1,  1, -1},
  135.        { 1, -2, -1},
  136.        { 1,  1, -1} };
  137.  
  138. short prewitt_mask_3[3][3] =  {
  139.        { 1, -1, -1},
  140.        { 1, -2, -1},
  141.        { 1,  1,  1} };
  142.  
  143. short prewitt_mask_4[3][3] =  {
  144.        {-1, -1, -1},
  145.        { 1, -2,  1},
  146.        { 1,  1,  1} };
  147.  
  148. short prewitt_mask_5[3][3] =  {
  149.        {-1, -1,  1},
  150.        {-1, -2,  1},
  151.        { 1,  1,  1} };
  152.  
  153. short prewitt_mask_6[3][3] =  {
  154.        {-1,  1,  1},
  155.        {-1, -2,  1},
  156.        {-1,  1,  1} };
  157.  
  158. short prewitt_mask_7[3][3] =  {
  159.        { 1,  1,  1},
  160.        {-1, -2,  1},
  161.        {-1, -1,  1} };
  162.  
  163.  
  164.  
  165.  
  166.  
  167.  
  168.    /* masks for sobel operator */
  169.  
  170. short sobel_mask_0[3][3] =  {
  171.        { 1,  2,  1},
  172.        { 0,  0,  0},
  173.        {-1, -2, -1} };
  174.  
  175. short sobel_mask_1[3][3] =  {
  176.        { 2,  1,  0},
  177.        { 1,  0, -1},
  178.        { 0, -1, -2} };
  179.  
  180. short sobel_mask_2[3][3] =  {
  181.        { 1,  0, -1},
  182.        { 2,  0, -2},
  183.        { 1,  0, -1} };
  184. short sobel_mask_3[3][3] =  {
  185.        { 0, -1, -2},
  186.        { 1,  0, -1},
  187.        { 2,  1,  0} };
  188.  
  189. short sobel_mask_4[3][3] =  {
  190.        {-1, -2, -1},
  191.        { 0,  0,  0},
  192.        { 1,  2,  1} };
  193.  
  194. short sobel_mask_5[3][3] =  {
  195.        {-2, -1,  0},
  196.        {-1,  0,  1},
  197.        { 0,  1,  2} };
  198.  
  199. short sobel_mask_6[3][3] =  {
  200.        {-1,  0,  1},
  201.        {-2,  0,  2},
  202.        {-1,  0,  1} };
  203.  
  204. short sobel_mask_7[3][3] =  {
  205.        { 0,  1,  2},
  206.        {-1,  0,  1},
  207.        {-2, -1,  0} };
  208.  
  209.  
  210.  
  211.  
  212.  
  213.  
  214.   /**************************************************
  215.   *
  216.   *   detect_edges(...
  217.   *
  218.   *   This function detects edges in an area of one
  219.   *   image and sends the result to another image
  220.   *   on disk.  It reads the input image from disk,
  221.   *   calls a convolution function, and then writes
  222.   *   the result out to disk.  If needed, it
  223.   *   allocates space on disk for the output image.
  224.   *
  225.   ***************************************************/
  226.  
  227.  
  228.  
  229.  
  230. detect_edges(in_name, out_name, the_image, out_image,
  231.              il, ie, ll, le, detect_type, threshold,
  232.              high)
  233.    char   in_name[], out_name[];
  234.    int    detect_type, high, il, ie,
  235.           ll, le, threshold;
  236.    short  the_image[ROWS][COLS], out_image[ROWS][COLS];
  237.  
  238. {
  239.    int    i, j, k, length, width;
  240.    struct tiff_header_struct image_header;
  241.  
  242.  
  243.    create_file_if_needed(in_name, out_name, out_image);
  244.  
  245.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  246.  
  247.    read_tiff_header(in_name, &image_header);
  248.  
  249.    perform_convolution(the_image, out_image,
  250.                        detect_type, threshold,
  251.                        &image_header, high);
  252.  
  253.    fix_edges(out_image, 1);
  254.  
  255.    write_array_into_tiff_image(out_name, out_image,
  256.                                il, ie, ll, le);
  257. }  /* ends detect_edges */
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.      /**********************************************************
  266.      *
  267.      *   perform_convolution(...
  268.      *
  269.      *   This function performs convolution between the input
  270.      *   image and 8 3x3 masks.  The result is placed in
  271.      *   the out_image.
  272.      *
  273.      ********************************************************/
  274.  
  275. perform_convolution(image, out_image,
  276.                     detect_type, threshold,
  277.                     image_header, high)
  278.    short image[ROWS][COLS],
  279.          out_image[ROWS][COLS];
  280.    int   detect_type, high, threshold;
  281.    struct tiff_header_struct *image_header;
  282. {
  283.  
  284.    int a,
  285.        b,
  286.        i,
  287.        is_present,
  288.        j,
  289.        sum;
  290.  
  291.    short  mask_0[3][3],
  292.           mask_1[3][3],
  293.           mask_2[3][3],
  294.           mask_3[3][3],
  295.           mask_4[3][3],
  296.           mask_5[3][3],
  297.           mask_6[3][3],
  298.           mask_7[3][3],
  299.           max,
  300.           min,
  301.           new_hi,
  302.           new_low;
  303.  
  304.  
  305.    setup_masks(detect_type, mask_0, mask_1,
  306.                mask_2, mask_3, mask_4, mask_5,
  307.                mask_6, mask_7);
  308.  
  309.    new_hi  = 250;
  310.    new_low = 16;
  311.    if(image_header->bits_per_pixel == 4){
  312.        new_hi  = 10;
  313.        new_low = 3;
  314.    }
  315.  
  316.    min = 0;
  317.    max = 255;
  318.    if(image_header->bits_per_pixel == 4)
  319.       max = 16;
  320.  
  321.      /* clear output image array */
  322.    for(i=0; i<ROWS; i++)
  323.       for(j=0; j<COLS; j++)
  324.          out_image[i][j] = 0;
  325.  
  326.    printf("\n ");
  327.  
  328.    for(i=1; i<ROWS-1; i++){
  329.       if( (i%10) == 0) printf("%3d", i);
  330.       for(j=1; j<COLS-1; j++){
  331.  
  332.  
  333.          /* Convolve for all 8 directions */
  334.  
  335.          /* 0 direction */
  336.  
  337.       sum = 0;
  338.       for(a=-1; a<2; a++){
  339.          for(b=-1; b<2; b++){
  340.             sum = sum + image[i+a][j+b] *
  341.                   mask_0[a+1][b+1];
  342.          }
  343.       }
  344.          if(sum > max) sum = max;
  345.          if(sum < 0)   sum = 0;
  346.             /* Correction 12-27-92
  347.                see file header for
  348.                details. */
  349.       if(sum > out_image[i][j])
  350.          out_image[i][j]   = sum;
  351.  
  352.  
  353.          /* 1 direction */
  354.  
  355.       sum = 0;
  356.       for(a=-1; a<2; a++){
  357.          for(b=-1; b<2; b++){
  358.             sum = sum + image[i+a][j+b] * mask_1[a+1][b+1];
  359.          }
  360.       }
  361.          if(sum > max) sum = max;
  362.          if(sum < 0)   sum = 0;
  363.